package com.bruce.tool.pay.wechat.app.back;

import com.alibaba.fastjson.JSON;
import com.bruce.tool.common.util.string.MapHandler;
import com.bruce.tool.common.util.string.XmlUtils;
import com.bruce.tool.pay.wechat.app.to.AppPayWxTo;
import com.bruce.tool.pay.wechat.app.to.AppPayWxVo;
import com.bruce.tool.pay.wechat.qrcode.WXPayUtil;
import com.bruce.tool.pay.wechat.sign.WxPaySignUtil;
import com.bruce.tool.rpc.http.core.Https;
import com.bruce.tool.rpc.http.handler.sign.SignInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 预订单信息拼接工具类
 * 0.定义通用化参数
 * 1.完成参数签名
 * 2.完成参数拼接
 *
 * @author Bruce(刘正航)
 */
@Slf4j
public class WxAppPayHelper {

    private static String wx_notify_url = "http://118.31.77.86:18181/payment/payCallback";
    private static String wx_app_key = "kuaigongwangluo91330110ma27wwbf1";
    private static String wx_pay_secret = "d7da7e5ba5c9faf9f3d8ee87e7994d27";
    private static String appid = "wx8dd9d756d12032a3";
    private static String mchid = "1490727912";

    public static void init(String appId, String mchId, String appKey, String appSecret, String notifyUrl) {
        appid = appId;
        mchid = mchId;
        wx_app_key = appKey;
        wx_pay_secret = appSecret;
        wx_notify_url = notifyUrl;
    }

    /**
     * 拼接参数,并调用统一下单接口
     */
    public static AppPayWxVo joinAndPrePay(AppPayWxTo wapPayWxTo, String ipAddress) {
        MapHandler params = MapHandler.build()
                .add("body", wapPayWxTo.getSubject())
                .add("out_trade_no", wapPayWxTo.getOrderNo())
                .add("total_fee", wapPayWxTo.getTotalAmount())
                .add("nonce_str", WXPayUtil.generateNonceStr())
                .add("spbill_create_ip", ipAddress)
                .add("notify_url", wx_notify_url)
                .add("trade_type", "APP")
                .add("fee_type", "CNY")
                .add("appid", appid)
                .add("mch_id", mchid);
        if (StringUtils.isNotBlank(wapPayWxTo.getPassbackParams())) {
            params.add("attach", Https.urlEncode(wapPayWxTo.getPassbackParams()));
        }
        SortedMap<String, Object> sortedMap = new TreeMap<>(params);
        // 微信统一支付接口
        String payResult = Https.create().url("https://api.mch.weixin.qq.com/pay/unifiedorder")
                .addAllBodys(sortedMap)
                .signature(new SignInfo(wx_app_key, wx_pay_secret, ""), (signInfo, requestInfo) -> {
                    String signature = WxPaySignUtil.signature(wx_app_key, requestInfo.getBodyParams());
                    requestInfo.getBodyParams().put("sign", signature);
                })
                .print(true)
                .postXml();
        if (Objects.isNull(payResult)) {
            return new AppPayWxVo();
        }
        Map<String, Object> map = XmlUtils.toMap(payResult, StandardCharsets.UTF_8.displayName());
        if (CollectionUtils.isEmpty(map)) {
            return new AppPayWxVo();
        }
        map.put("timestamp", System.currentTimeMillis() / 1000);
        String signature = WxPaySignUtil.signature(wx_app_key, map);
        map.put("spbill_create_ip", ipAddress);
        map.put("package", "Sign=WXPay");
        map.put("sign", signature);
        return JSON.parseObject(JSON.toJSONString(map), AppPayWxVo.class);
    }

    public static void main(String[] args) {
        WxAppPayHelper.init("", "", "", "", "");
        AppPayWxTo wx = JSON.parseObject("{\n" +
                "\t\"body\":\"测试支付宝-网页支付\",\n" +
                "\t\"total_fee\":\"1\",\n" +
                "\t\"out_trade_no\":\"12809328138\",\n" +
                "\t\"attach\":\"a%3D1%26b%3D2\"\n" +
                "}", AppPayWxTo.class);
        System.out.println(WxAppPayHelper.joinAndPrePay(wx, ""));
    }
}
